home *** CD-ROM | disk | FTP | other *** search
/ The Fatted Calf / The Fatted Calf.iso / Unix / Shells / zsh / Source / src / init.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-04-07  |  15.6 KB  |  710 lines

  1. /*
  2.  *
  3.  * init.c - main loop and initialization routines
  4.  *
  5.  * This file is part of zsh, the Z shell.
  6.  *
  7.  * This software is Copyright 1992 by Paul Falstad
  8.  *
  9.  * Permission is hereby granted to copy, reproduce, redistribute or otherwise
  10.  * use this software as long as: there is no monetary profit gained
  11.  * specifically from the use or reproduction of this software, it is not
  12.  * sold, rented, traded or otherwise marketed, and this copyright notice is
  13.  * included prominently in any copy made.
  14.  *
  15.  * The author make no claims as to the fitness or correctness of this software
  16.  * for any use whatsoever, and it is provided as is. Any use of this software
  17.  * is at the user's own risk.
  18.  *
  19.  */
  20.  
  21. #define GLOBALS
  22. #include "zsh.h"
  23. #include <pwd.h>
  24.  
  25. static int noexitct = 0;
  26.  
  27. void main(argc, argv, envp)    /**/
  28. int argc;
  29. char **argv;
  30. char **envp;
  31. {
  32.     char *zshname;
  33.  
  34. #ifdef LC_ALL
  35.     setlocale(LC_ALL, "");
  36. #endif
  37.     environ = envp;
  38.     permalloc();
  39.     if (!(zshname = strrchr(argv[0], '/')))
  40.     zshname = argv[0];
  41.     else
  42.     zshname++;
  43.     if ( *zshname == '-' ) zshname++;
  44.     setflags(zshname);
  45.     parseargs(argv);
  46.     setmoreflags();
  47.     setupvals(zshname);
  48.     initialize();
  49.     heapalloc();
  50.     runscripts(zshname);
  51.     for (;;) {
  52.     do
  53.         loop(1);
  54.     while (tok != ENDINPUT);
  55.     if (!(isset(IGNOREEOF) && interact)) {
  56. #if 0
  57.         if (interact)
  58.         fputs(islogin ? "logout\n" : "exit\n", stderr);
  59. #endif
  60.         zexit(lastval);
  61.         continue;
  62.     }
  63.     noexitct++;
  64.     if (noexitct >= 10) {
  65.         stopmsg = 1;
  66.         zexit(lastval);
  67.     }
  68.     zerrnam("zsh", (!islogin) ? "use 'exit' to exit."
  69.         : "use 'logout' to logout.", NULL, 0);
  70.     }
  71. }
  72.  
  73. /* keep executing lists until EOF found */
  74.  
  75. void loop(toplevel)        /**/
  76. int toplevel;
  77. {
  78.     List list;
  79.  
  80.     pushheap();
  81.     for (;;) {
  82.     freeheap();
  83.     errflag = 0;
  84.     if (interact && isset(SHINSTDIN))
  85.         preprompt();
  86.     hbegin();        /* init history mech */
  87.     intr();            /* interrupts on */
  88.     ainit();        /* init alias mech */
  89.     lexinit();
  90.     if (!(list = parse_event())) {    /* if we couldn't parse a list */
  91.         hend();
  92.         if (tok == ENDINPUT && !errflag)
  93.         break;
  94.         continue;
  95.     }
  96.     if (hend()) {
  97.         if (stopmsg)    /* unset 'you have stopped jobs' flag */
  98.         stopmsg--;
  99.         execlist(list);
  100.         if (toplevel)
  101.         noexitct = 0;
  102.     }
  103.     if (ferror(stderr)) {
  104.         zerr("write error", NULL, 0);
  105.         clearerr(stderr);
  106.     }
  107.     if (subsh)        /* how'd we get this far in a subshell? */
  108.         exit(lastval);
  109.     if (((!interact || sourcelevel) && errflag) || retflag)
  110.         break;
  111.     if (trapreturn) {
  112.         lastval = trapreturn;
  113.         trapreturn = 0;
  114.     }
  115.     if (isset('t') && toplevel) {
  116.         if (sigtrapped[SIGEXIT])
  117.         dotrap(SIGEXIT);
  118.         exit(lastval);
  119.     }
  120.     }
  121.     popheap();
  122. }
  123.  
  124. void setflags(zshname)        /**/
  125. const char *zshname;
  126. {
  127.     int c;
  128.  
  129.     for (c = 0; c != 42; c++)
  130.     opts[c] = OPT_UNSET;
  131.     for (c = 42; c != 128; c++)
  132.     opts[c] = OPT_INVALID;
  133.     for (c = 'a'; c <= 'z'; c++)
  134.     opts[c] = opts[c - 'a' + 'A'] = OPT_UNSET;
  135.     for (c = '0'; c <= '9'; c++)
  136.     opts[c] = OPT_UNSET;
  137.     opts['A'] = OPT_INVALID;
  138.     opts['i'] = (isatty(0)) ? OPT_SET : OPT_UNSET;
  139.     opts[BGNICE] = opts[NOTIFY] = OPT_SET;
  140.     opts[USEZLE] = (interact && SHTTY != -1) ? OPT_SET : OPT_UNSET;
  141.     opts[HASHCMDS] = opts[HASHLISTALL] = opts[HASHDIRS] = OPT_SET;
  142.  
  143. /* Bourne/Korn mode:
  144.         The following seven options cause zsh to behave more like
  145.         Bourne and Korn shells when invoked as "sh" or "ksh".
  146.         K - don't recognize csh-style history subst
  147.         k - allow interactive comments
  148.         I - don't perform brace expansion
  149.         3 - don't print error for unmatched wildcards
  150.         H - don't query 'rm *'
  151.         y - split parameters using IFS
  152.         KSHOPTIONPRINT - print options ksh-like
  153.          -- wnp@rcvie.co.at, 1992-05-14
  154.     */
  155.  
  156.     if (strcmp(zshname, "sh") == 0 || strcmp(zshname, "ksh") == 0) {
  157.     opts['K'] = opts['k'] = opts['I'] = opts['3'] = OPT_SET;
  158.     opts['H'] = opts['y'] = opts[KSHOPTIONPRINT] = OPT_SET;
  159.     }
  160. }
  161.  
  162. static char *cmd;
  163. static int opti = OPT_UNSET;
  164.  
  165. void parseargs(argv)        /**/
  166. char **argv;
  167. {
  168.     char **x;
  169.     int bk = 0, action;
  170.     Lklist paramlist;
  171.  
  172.     hackzero = argzero = *argv;
  173.     opts[LOGINSHELL] = (**(argv++) == '-') ? OPT_SET : OPT_UNSET;
  174.     SHIN = 0;
  175.     while (!bk && *argv && (**argv == '-' || **argv == '+')) {
  176.     action = (**argv == '-') ? OPT_SET : OPT_UNSET;
  177.     while (*++*argv) {
  178.         if ((bk = (**argv == 'b' || **argv == '-')))
  179.         break;
  180.         if (opts[(int)**argv] == OPT_INVALID) {
  181.         zerr("bad option: -%c", NULL, **argv);
  182.         exit(1);
  183.         }
  184.         if (**argv == 'c') {/* -c command */
  185.         argv++;
  186.         if (!*argv) {
  187.             zerr("string expected after -c", NULL, 0);
  188.             exit(1);
  189.         }
  190.         cmd = *argv;
  191.         opts[INTERACTIVE] = opti;
  192.         opts['c'] = OPT_SET;
  193.         bk = 1;
  194.         break;
  195.         } else if (**argv == 'o') {
  196.         int c;
  197.  
  198.         if (!*++*argv)
  199.             argv++;
  200.         if (!*argv) {
  201.             zerr("string expected after -o", NULL, 0);
  202.             exit(1);
  203.         }
  204.         c = optlookup(*argv);
  205.         if (c == -1)
  206.             zerr("no such option: %s", *argv, 0);
  207.         else {
  208.             if (c == 'i')
  209.             opti = action;
  210.             opts[c] = action;
  211.         }
  212.         break;
  213.         } else {
  214.         if (**argv == 'i')
  215.             opti = action;
  216.         opts[(int)**argv] = action;
  217.         }
  218.     }
  219.     argv++;
  220.     }
  221.     paramlist = newlist();
  222.     if (*argv) {
  223.     if (opts[SHINSTDIN] == OPT_UNSET) {
  224.         argzero = *argv;
  225.         if (opts['c'] == OPT_UNSET)
  226.         SHIN = movefd(open(argzero, O_RDONLY));
  227.         if (SHIN == -1) {
  228.         zerr("can't open input file: %s", argzero, 0);
  229.         exit(1);
  230.         }
  231.         opts[INTERACTIVE] = opti;
  232.         argv++;
  233.     }
  234.     while (*argv)
  235.         addnode(paramlist, ztrdup(*argv++));
  236.     } else
  237.     opts[SHINSTDIN] = OPT_SET;
  238.     pparams = x = (char **)zcalloc((countnodes(paramlist) + 1) * sizeof(char *));
  239.  
  240.     while ((*x++ = (char *)getnode(paramlist)));
  241.     free(paramlist);
  242.     argzero = ztrdup(argzero);
  243. }
  244.  
  245. void setmoreflags()
  246. {                /**/
  247. #ifndef NOCLOSEFUNNYFDS
  248.     int t0;
  249.  
  250. #endif
  251.     long ttpgrp;
  252.  
  253. /* stdout,stderr fully buffered */
  254. #ifdef _IOFBF
  255.     setvbuf(stdout, malloc(BUFSIZ), _IOFBF, BUFSIZ);
  256.     setvbuf(stderr, malloc(BUFSIZ), _IOFBF, BUFSIZ);
  257. #else
  258.     setbuffer(stdout, malloc(BUFSIZ), BUFSIZ);
  259.     setbuffer(stderr, malloc(BUFSIZ), BUFSIZ);
  260. #endif
  261.     subsh = 0;
  262. #ifndef NOCLOSEFUNNYFDS
  263. /* this works around a bug in some versions of in.rshd */
  264.     if (isset('c'))
  265.     for (t0 = 3; t0 != 10; t0++)
  266.         close(t0);
  267. #endif
  268. #ifdef JOB_CONTROL
  269.     opts[MONITOR] = (interact) ? OPT_SET : OPT_UNSET;
  270.     if (jobbing) {
  271.     SHTTY = movefd((isatty(0)) ? dup(0) : open("/dev/tty", O_RDWR));
  272.     if (SHTTY == -1)
  273.         opts[MONITOR] = OPT_UNSET;
  274.     else {
  275. #if defined(TIOCSETD) && defined(NTTYDISC)
  276.         int ldisc = NTTYDISC;
  277.  
  278.         ioctl(SHTTY, TIOCSETD, (char *) &ldisc);
  279. #endif
  280.         gettyinfo(&shttyinfo);    /* get tty state */
  281. #if defined(__sgi)
  282.         if (shttyinfo.tio.c_cc[VSWTCH] <= 0)    /* hack for irises */
  283.         shttyinfo.tio.c_cc[VSWTCH] = CSWTCH;
  284. #endif
  285.     }
  286. #if defined(__sgi) || defined(__386BSD__) || defined(__NetBSD__) || defined(__FreeBSD__)
  287.     attachtty(GETPGRP());
  288. #endif
  289.     if ((mypgrp = GETPGRP()) <= 0)
  290.         opts[MONITOR] = OPT_UNSET;
  291.     else
  292.         while ((ttpgrp = gettygrp()) != -1 && ttpgrp != mypgrp) {
  293.         sleep(1);
  294.         mypgrp = GETPGRP();
  295.         if (mypgrp == gettygrp())
  296.             break;
  297.         killpg(mypgrp, SIGTTIN);
  298.         mypgrp = GETPGRP();
  299.         }
  300.     } else
  301.     SHTTY = -1;
  302. #else
  303.     opts[MONITOR] = OPT_UNSET;
  304.     SHTTY = movefd((isatty(0)) ? dup(0) : open("/dev/tty", O_RDWR));
  305.     if (SHTTY != -1)
  306.     gettyinfo(&shttyinfo);
  307. #endif
  308. }
  309.  
  310. SPROTO(long get_baudrate, (int speedcode));
  311.  
  312. static long get_baudrate(speedcode)
  313. int speedcode;
  314. {
  315.     switch (speedcode) {
  316.     case B0:
  317.     return (0L);
  318.     case B50:
  319.     return (50L);
  320.     case B75:
  321.     return (75L);
  322.     case B110:
  323.     return (110L);
  324.     case B134:
  325.     return (134L);
  326.     case B150:
  327.     return (150L);
  328.     case B200:
  329.     return (200L);
  330.     case B300:
  331.     return (300L);
  332.     case B600:
  333.     return (600L);
  334. #ifdef _B900
  335.     case _B900:
  336.     return (900L);
  337. #endif
  338.     case B1200:
  339.     return (1200L);
  340.     case B1800:
  341.     return (1800L);
  342.     case B2400:
  343.     return (2400L);
  344. #ifdef _B3600
  345.     case _B3600:
  346.     return (3600L);
  347. #endif
  348.     case B4800:
  349.     return (4800L);
  350. #ifdef _B7200
  351.     case _B7200:
  352.     return (7200L);
  353. #endif
  354.     case B9600:
  355.     return (9600L);
  356. #ifdef B19200
  357.     case B19200:
  358.     return (19200L);
  359. #else
  360. #ifdef EXTA
  361.     case EXTA:
  362.     return (19200L);
  363. #endif
  364. #endif
  365. #ifdef B38400
  366.     case B38400:
  367.     return (38400L);
  368. #else
  369. #ifdef EXTB
  370.     case EXTB:
  371.     return (38400L);
  372. #endif
  373. #endif
  374.     default:
  375.     break;
  376.     }
  377.     return (0L);
  378. }
  379.  
  380. void setupvals(zshname)        /**/
  381. const char *zshname;
  382. {
  383.     struct passwd *pswd;
  384.     char *ptr;
  385.     struct timezone dummy_tz;
  386.  
  387.     noeval = 0;
  388.     curhist = 0;
  389.     histsiz = DEFAULT_HISTSIZE;
  390.     lithistsiz = 5;
  391.     inithist();
  392.     mailcheck = logcheck = 60;
  393.     keytimeout = 40;
  394.     dirstacksize = -1;
  395.     listmax = 100;
  396.     clwords = (char **)zcalloc((clwsize = 16) * sizeof(char *));
  397.  
  398.     cmdstack = (unsigned char *)zalloc(256);
  399.     cmdsp = 0;
  400.  
  401.     reporttime = -1;
  402.     bangchar = '!';
  403.     hashchar = '#';
  404.     hatchar = '^';
  405.     termok = 0;
  406.     curjob = prevjob = coprocin = coprocout = -1;
  407.     gettimeofday(&shtimer, &dummy_tz);    /* init $SECONDS */
  408.     srand((unsigned int)shtimer.tv_sec);
  409. /* build various hash tables; argument to newhtable is table size */
  410.     aliastab = newhtable(37);
  411.     addreswords();
  412.     addhnode(ztrdup("run-help"), mkanode(ztrdup("man"), 1), aliastab, NULL);
  413.     addhnode(ztrdup("which-command"),
  414.          mkanode(ztrdup("whence"), 1), aliastab, NULL);
  415.     paramtab = newhtable(151);
  416.     cmdnamtab = newhtable(37);
  417.     compctltab = newhtable(13);
  418.     initxbindtab();
  419.  
  420. /* Bourne/Korn mode:
  421.         The following variable assignments cause zsh to behave more
  422.         like Bourne and Korn shells when invoked as "sh" or "ksh".
  423.         NULLCMD=":"
  424.         READNULLCMD=":"
  425.          -- chip@fin.uucp, 1992-06-15
  426.     */
  427.     if (strcmp(zshname, "sh") == 0 || strcmp(zshname, "ksh") == 0) {
  428.     nullcmd = ztrdup(":");
  429.     readnullcmd = ztrdup(":");
  430.     } else {
  431.     nullcmd = ztrdup("cat");
  432.     readnullcmd = ztrdup("more");
  433.     }
  434.  
  435.     prompt = ztrdup("%m%# ");
  436.     prompt2 = ztrdup("> ");
  437.     prompt3 = ztrdup("?# ");
  438.     prompt4 = ztrdup("+ ");
  439.     sprompt = ztrdup("zsh: correct `%R' to `%r' [nyae]? ");
  440.     term = ztrdup("");
  441.     ppid = getppid();
  442. #ifdef HAS_TIO
  443. #if defined(HAS_TCCRAP) && defined(HAS_TERMIOS)
  444.     baud = cfgetospeed(&shttyinfo.tio);
  445.     if (baud < 100)
  446.     baud = get_baudrate((int)baud);    /* aren't "standards" great?? */
  447. #else
  448.     baud = get_baudrate(shttyinfo.tio.c_cflag & CBAUD);
  449. #endif
  450. #else
  451.     baud = get_baudrate(shttyinfo.sgttyb.sg_ospeed);
  452. #endif
  453. #ifdef TIOCGWINSZ
  454.     if (!(columns = shttyinfo.winsize.ws_col))
  455.     columns = 80;
  456.     if (!(lines = shttyinfo.winsize.ws_row))
  457.     lines = 24;
  458. #else
  459.     columns = 80;
  460.     lines = 24;
  461. #endif
  462.     ifs = ztrdup(" \t\n");
  463.     timefmt = ztrdup(DEFTIMEFMT);
  464.     watchfmt = ztrdup(DEFWATCHFMT);
  465.     if (!(ttystrname = ztrdup(ttyname(SHTTY))))
  466.     ttystrname = ztrdup("");
  467.     wordchars = ztrdup(DEFWORDCHARS);
  468.     fceditparam = ztrdup(DEFFCEDIT);
  469.     tmpprefix = ztrdup(DEFTMPPREFIX);
  470.     postedit = ztrdup("");
  471.     hostnam = (char *)zalloc(256);
  472.     underscore = ztrdup("");
  473.     gethostname(hostnam, 256);
  474.     mypid = getpid();
  475.     cdpath = mkarray(NULL);
  476.     manpath = mkarray(NULL);
  477.     fignore = mkarray(NULL);
  478.     fpath = mkarray(NULL);
  479.     mailpath = mkarray(NULL);
  480.     watch = mkarray(NULL);
  481.     psvar = mkarray(NULL);
  482.     compctlsetup();
  483.     namdirs = (Nameddirs) zcalloc(sizeof(*namdirs) * 2);
  484.     userdirsz = 2;
  485.     userdirct = 0;
  486.     zoptarg = ztrdup("");
  487.     zoptind = 1;
  488.     schedcmds = NULL;
  489.     path = (char **)zalloc(4 * sizeof *path);
  490.     path[0] = ztrdup("/bin");
  491.     path[1] = ztrdup("/usr/bin");
  492.     path[2] = ztrdup("/usr/ucb");
  493.     path[3] = NULL;
  494.     inittyptab();
  495.     initlextabs();
  496.     setupparams();
  497.  
  498.     if (!home ||
  499. #ifdef SYSV
  500.     !(username = cuserid(NULL))
  501. #else
  502.       !(username = getlogin())
  503. #endif
  504.       ) {
  505.     if ((pswd = getpwuid(getuid()))) {
  506.         username = ztrdup(pswd->pw_name);
  507.         if(!home)
  508.         home = ztrdup(pswd->pw_dir);
  509.     } else {
  510.         username = ztrdup("");
  511.         if (!home)
  512.         home = ztrdup("/");
  513.     }
  514.     }
  515.     if ((ptr = zgetenv("LOGNAME")))
  516.     zlogname = ztrdup(ptr);
  517.     else
  518.     zlogname = ztrdup(username);
  519.  
  520.     if (ispwd(home))
  521.     pwd = ztrdup(home);
  522.     else if ((ptr = zgetenv("PWD")) && ispwd(ptr))
  523.     pwd = ztrdup(ptr);
  524.     else
  525.     pwd = zgetwd();
  526.     oldpwd = ztrdup(pwd);
  527.  
  528.     setparams();
  529.  
  530.     inittyptab();
  531.     if (!strcmp(term, "emacs"))
  532.     opts[USEZLE] = OPT_UNSET;
  533. #ifndef HAS_RUSAGE
  534.     times(&shtms);
  535. #endif
  536. }
  537.  
  538. void compctlsetup()
  539. {                /**/
  540.     static char
  541.     *os[] =
  542.     {"setopt", "unsetopt", NULL}, *vs[] =
  543.     {"export", "typeset", "vared", "unset", NULL}, *cs[] =
  544.     {"which", "builtin", NULL}, *bs[] =
  545.     {"bindkey", NULL};
  546.  
  547.     compctl_process(os, CC_OPTIONS, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
  548.             NULL, NULL, 0);
  549.     compctl_process(vs, CC_VARS, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
  550.             NULL, NULL, 0);
  551.     compctl_process(bs, CC_BINDINGS, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
  552.             NULL, NULL, 0);
  553.     compctl_process(cs, CC_COMMPATH, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
  554.             NULL, NULL, 0);
  555.     cc_compos.mask = CC_COMMPATH;
  556.     cc_default.refc = 10000;
  557.     cc_default.mask = CC_FILES;
  558. }
  559.  
  560. void initialize()
  561. {                /**/
  562. #ifdef RLIM_INFINITY
  563.     int t0;
  564. #endif
  565.  
  566.     breaks = loops = 0;
  567.     lastmailcheck = time(NULL);
  568.     locallist = NULL;
  569.     locallevel = sourcelevel = 0;
  570.     trapreturn = 0;
  571.     dirstack = newlist();
  572.     bufstack = newlist();
  573.     newcmdnamtab();
  574.     inbuf = (char *)zalloc(inbufsz = 256);
  575.     inbufptr = inbuf + inbufsz;
  576.     inbufct = 0;
  577. #ifdef RLIM_INFINITY
  578.     for (t0 = 0; t0 != RLIM_NLIMITS; t0++)
  579.     getrlimit(t0, limits + t0);
  580. #endif
  581.     hsubl = hsubr = NULL;
  582.     lastpid = 0;
  583.     bshin = fdopen(SHIN, "r");
  584.     intr();
  585. #ifndef QDEBUG
  586.     sig_ignore(SIGQUIT);
  587. #endif
  588.     sig_handle(SIGHUP);
  589.     sig_handle(SIGCHLD);
  590.     if (interact) {
  591.     sig_handle(SIGALRM);
  592. #ifdef SIGWINCH
  593.     sig_handle(SIGWINCH);
  594. #endif
  595.     sig_ignore(SIGTERM);
  596.     }
  597.     if (jobbing) {
  598.     long ttypgrp;
  599.  
  600.     while ((ttypgrp = gettygrp()) != -1 && ttypgrp != mypgrp)
  601.         kill(0, SIGTTIN);
  602.     if (ttypgrp == -1) {
  603.         opts[MONITOR] = OPT_UNSET;
  604.     } else {
  605.         sig_ignore(SIGTTOU);
  606.         sig_ignore(SIGTSTP);
  607.         sig_ignore(SIGTTIN);
  608.         sig_ignore(SIGPIPE);
  609.         attachtty(mypgrp);
  610.     }
  611.     }
  612. #ifdef SIGNAL_MASKS
  613.     if (islogin) {
  614.     sig_setmask(sig_mask(0));
  615.     }
  616.     else if (interact) {
  617.     sigset_t set;
  618.     sigemptyset(&set);
  619.     sigaddset(&set, SIGINT);
  620.     sigaddset(&set, SIGQUIT);
  621.     sig_unblock(set);
  622.     }
  623. #endif /* SIGNAL_MASKS */
  624. }
  625.  
  626. void addreswords()
  627. {                /**/
  628.     static char *reswds[] =
  629.     {
  630.     "do", "done", "esac", "then", "elif", "else", "fi", "for", "case",
  631.     "if", "while", "function", "repeat", "time", "until", "exec", "command",
  632.     "select", "coproc", "noglob", "-", "nocorrect", "foreach", "end", NULL
  633.     };
  634.     int t0;
  635.  
  636.     for (t0 = 0; reswds[t0]; t0++)
  637.     addhnode(ztrdup(reswds[t0]), mkanode(NULL, -1 - t0), aliastab, NULL);
  638. }
  639.  
  640. void runscripts(zshname)    /**/
  641. char *zshname;
  642. {
  643. /*
  644.        KSH Mode:
  645.        if called as "ksh", we source the standard
  646.        sh/ksh scripts:
  647.        wnp@rcvie.co.at 1992/05/14
  648.      */
  649.  
  650.     sourcelevel = 32768;    /* hack to avoid errexit in init scripts */
  651.  
  652.     if (strcmp(zshname, "ksh") == 0) {
  653.     if (islogin)
  654.         source("/etc/profile");
  655.     if (islogin)
  656.         sourcehome(".profile");
  657.     source(getsparam("ENV"));
  658.     } else {
  659. #ifdef GLOBALZSHENV
  660.     source(GLOBALZSHENV);
  661. #endif
  662.     if (!isset(NORCS)) {
  663.         sourcehome(".zshenv");
  664.         if (islogin) {
  665. #ifdef GLOBALZPROFILE
  666.         source(GLOBALZPROFILE);
  667. #endif
  668.         sourcehome(".zprofile");
  669.         }
  670.         if (interact) {
  671. #ifdef GLOBALZSHRC
  672.         source(GLOBALZSHRC);
  673. #endif
  674.         sourcehome(".zshrc");
  675.         }
  676.         if (islogin) {
  677. #ifdef GLOBALZLOGIN
  678.         source(GLOBALZLOGIN);
  679. #endif
  680.         sourcehome(".zlogin");
  681.         }
  682.     }
  683.     }
  684.  
  685.     if (isset('c')) {
  686.     if (SHIN >= 10)
  687.         close(SHIN);
  688.     SHIN = movefd(open("/dev/null", O_RDONLY));
  689.     execstring(cmd);
  690.     stopmsg = 1;
  691.     zexit(lastval);
  692.     }
  693.     if (interact && !isset(NORCS))
  694.     readhistfile(getsparam("HISTFILE"), 0);
  695. #ifdef TIOCGWINSZ
  696.     adjustwinsize();
  697. #endif
  698.     if (isset('t') && opti == OPT_UNSET)
  699.     prompt = ztrdup("");
  700.  
  701.     sourcelevel = 0;
  702. }
  703.  
  704. void ainit()
  705. {                /**/
  706.     alstackind = 0;        /* reset alias stack */
  707.     alstat = 0;
  708.     isfirstln = 1;
  709. }
  710.